/**
 * 单位树组件
 */

import styled from '@emotion/styled';
import { Spin, Tree } from 'antd';
import { EventDataNode } from 'antd/es/tree';
import { BasicDataNode } from 'rc-tree/lib/interface';
import { memo, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
import { useRecoilState } from 'recoil';


import { userState } from '../../stores/user';
import { request } from '../../utils/request';
import { SysUnitTree, useGetUnitTree } from '../../service/unit-service';
import { IRoleRestFillRefHandler } from '../../types';

interface IUnitTreeProps {
  getCheckUnit: (unitId: string, unitName: string) => void;
  onRef?: React.MutableRefObject<IRoleRestFillRefHandler | undefined>;
}

interface DataNode {
  title: string;
  key: string;
  isLeaf: boolean;
  children?: DataNode[];
}

const UnitTree = ({ getCheckUnit, onRef }: IUnitTreeProps) => {
  const [user] = useRecoilState(userState);
  const [queryParams] = useState<{ unitId: string }>({
    unitId: user.userInfo.unitId || '',
  });
  const checkUnit = useRef<{ unitId: string, unitName: string }>()
  const { data: dataSource, refetch, isLoading } = useGetUnitTree(queryParams);
  const [treeData, setTreeData] = useState<DataNode[]>();
  /**向外暴露的重置方法 */
  useImperativeHandle(onRef, () => ({
    rest: () => {
      setTimeout(() => {
        refetch();
      }, 1000);
    },
    fill: (key: number) => {
      console.log(key);
    },
    getData: () => {
      return checkUnit.current ? { value: checkUnit.current.unitId, name: checkUnit.current.unitName } : { value: dataSource?.unitId || '', name: dataSource?.unitName || '' };
    }
  }));
  useEffect(() => {
    if (dataSource) {
      const data: DataNode[] = [
        {
          title: dataSource.unitName,
          key: dataSource.unitId,
          isLeaf: dataSource.isParent === 1 ? false : true,
        },
      ];
      const children: DataNode[] = [];
      if (dataSource.children && dataSource.children.length > 0) {
        dataSource.children.forEach((ele) => {
          children.push({
            title: ele.unitName,
            key: ele.unitId,
            isLeaf: ele.isParent === 1 ? false : true,
          });
        });
      }
      data[0].children = children;
      setTreeData(data);
    }
  }, [dataSource]);

  /**点击单位的回调 */
  const onSelect = (selectedKeys: React.Key[], info: { node: any }) => {
    const unitId = selectedKeys[0] as string;
    const unitName = info.node.title;
    checkUnit.current = { unitId: unitId, unitName: unitName };
    getCheckUnit(unitId, unitName);
  };
  /**点击加载子单位回调 */
  const onLoadData = async ({ key }: EventDataNode<BasicDataNode>) => {
    //root 节点不需要加载
    if (key !== user.userInfo.unitId) {
      const res = await request<SysUnitTree>('/unit/getUnitTreeById', {
        data: { unitId: key },
        token: user?.token || '',
      });
      setTreeData((origin) => updateTreeData(origin || [], key, res));
    } else {
      return new Promise<void>((resolve) => {
        resolve();
        return;
      });
    }
  };
  /**跟换后台数据生成树对象的数据 */
  const genTreeData = (res: SysUnitTree) => {
    return res.children.map((e) => {
      return {
        title: e.unitName,
        key: e.unitId,
        isLeaf: e.isParent === 1 ? false : true,
      };
    });
  };
  /**更新树对象 */
  const updateTreeData = (origin: DataNode[], key: string | number, res: SysUnitTree): DataNode[] => {
    return origin?.map((e) => {
      if (e.key === key) {
        return {
          ...e,
          children: genTreeData(res),
        };
      }
      if (e.children) {
        return {
          ...e,
          children: updateTreeData(e.children || [], key, res),
        };
      }
      return e;
    });
  };

  return (
    <UnitTreeContainer>
      <Spin spinning={isLoading}>
        {
          dataSource ? <Tree showLine={true} onSelect={onSelect} loadData={onLoadData} treeData={treeData} defaultSelectedKeys={[dataSource?.unitId || '']} /> : null
        }
      </Spin>
    </UnitTreeContainer>
  );
};

export default memo(UnitTree);

const UnitTreeContainer = styled.div``;
